package com.irdstudio.efp.esb.api.rest.psd.precredit;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.basic.framework.core.util.DateTool;
import com.irdstudio.efp.esb.api.bean.psd.precredit.req.NlsPsdPreCreditApprReqBean;
import com.irdstudio.efp.esb.api.bean.psd.precredit.resp.NlsPsdPreCreditApprRespBean;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.api.common.GroupeInterface;
import com.irdstudio.efp.esb.api.rest.EsbController;
import com.irdstudio.efp.esb.api.service.psd.NlsPsdPreCreditProcessServcie;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.constant.MsLoanConstant;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.nls.service.facade.psd.PreNlsCreditInfoService;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.psd.PreNlsCreditInfoVO;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

/**
 * 需求编号：【2019D1218】（普税贷需求）
 * 问题编号：【2019D1218】（普税贷预授信申请）
 * 开发人员：【ludayong】
 * 创建日期：【2019/12/16 10:11】
 * 功能描述：
 */

@RestController
@RequestMapping("esb")
public class NlsPsdPreCreditApprController implements EsbController {
    /**
     * 日志信息
     */
    private final Logger logger = LoggerFactory.getLogger(NlsPsdPreCreditApprController.class);

    @PostMapping("/SERVICE_30220001_14")
    public EsbRespServiceBean doRecv(@Validated @ModelAttribute("esbReqServiceBean") EsbReqServiceBean esbReqServiceBean, BindingResult bindingResult1,
                                     @Validated({GroupeInterface.psd.class}) @ModelAttribute("nlsPsdPreCreditApprReqBean") NlsPsdPreCreditApprReqBean nlsPsdPreCreditApprReqBean, BindingResult bindingResult2, Exception exception) {
        // 渠道申请号
        String chanAppNo = nlsPsdPreCreditApprReqBean.getChanAppNo();
        // 全局关联流水号
        String glblSrlNo = esbReqServiceBean.getSysHead().getGlblSrlNo();
        // 预授信申请响应信息
        NlsPsdPreCreditApprRespBean nlsPsdPreCreditApprRespBean = new NlsPsdPreCreditApprRespBean();
        try {
            logger.info("======>普税贷预授信接口【" + chanAppNo + "_30220001_14】开始<======");
            // 参数校验
            validateBean(esbReqServiceBean, bindingResult1, nlsPsdPreCreditApprReqBean, bindingResult2, exception, logger);
            // 设置系统头对象
            setSysHeadFieldThreadLocal(esbReqServiceBean);

            // 判断同一请求是否重复，如果申请号存在，直接返回
            PreNlsCreditInfoVO inPreCreditInfoByChannelApplyNo = new PreNlsCreditInfoVO();
            // 渠道申请号
            inPreCreditInfoByChannelApplyNo.setChannelApplyNo(chanAppNo);
            // 通过渠道申请号查询预授信申请信息
            PreNlsCreditInfoVO queryPreCreditInfoByChannelApplyNo = preNlsCreditInfoService.queryByChannelApplyNo(inPreCreditInfoByChannelApplyNo);
            if (Objects.nonNull(queryPreCreditInfoByChannelApplyNo)) {
                String msg = "同一渠道申请号重复申请！";
                return failureNotHandle(esbReqServiceBean, nlsPsdPreCreditApprReqBean, nlsPsdPreCreditApprRespBean, new BizException(msg), EsbRetCodeStandard.WFJKYWGZ);
            }

            // 判断同一请求是否重复，如果申请号存在，直接返回
            PreNlsCreditInfoVO inPreCreditInfoByGlblSrlNo = new PreNlsCreditInfoVO();
            // 全局流水号
            inPreCreditInfoByGlblSrlNo.setGlobalSerno(glblSrlNo);
            // 通过全局流水号查询预授信申请信息
            PreNlsCreditInfoVO queryPreCreditInfoByGlblSrlNo = preNlsCreditInfoService.queryByGlobalSerno(inPreCreditInfoByGlblSrlNo);
            if (Objects.nonNull(queryPreCreditInfoByGlblSrlNo)) {
                String msg = "同一全局流水号重复申请！";
                return failureNotHandle(esbReqServiceBean, nlsPsdPreCreditApprReqBean, nlsPsdPreCreditApprRespBean, new BizException(msg), EsbRetCodeStandard.WFJKYWGZ);
            }
            // 执行普税贷预授信申请并返回
            return nlsPsdPreCreditProcessServcie.processPreCreditApply(nlsPsdPreCreditApprReqBean, esbReqServiceBean);
        } catch (ESBException e) {
            logger.error("普税贷普税贷预授信申请接口出现异常，异常信息：[{}]", e.getMessage());
            e.printStackTrace();
            return failureHandler(esbReqServiceBean, nlsPsdPreCreditApprReqBean, nlsPsdPreCreditApprRespBean, e, EsbRetCodeStandard.JKYDCSJYBTG);
        } catch (BizException e) {
            logger.error("普税贷普税贷预授信申请接口出现异常，异常信息：[{}]", e.getMessage());
            e.printStackTrace();
            return failureHandler(esbReqServiceBean, nlsPsdPreCreditApprReqBean, nlsPsdPreCreditApprRespBean, e, EsbRetCodeStandard.WFJKYWGZ);
        } catch (Exception e) {
            logger.error("普税贷普税贷预授信申请接口出现异常，异常信息：[{}]", e.getMessage());
            e.printStackTrace();
            return failureHandler(esbReqServiceBean, nlsPsdPreCreditApprReqBean, nlsPsdPreCreditApprRespBean, e, EsbRetCodeStandard.OTHERS_EXCEPTION);
        } finally {
            logger.info("======>普税贷预授信接口【" + chanAppNo + "_30220001_14】结束<======");
        }
    }

    @ModelAttribute("esbReqServiceBean")
    public EsbReqServiceBean getReqEsbHeadBean(HttpServletRequest request) {
        logger.info("获取ESB请求系统头和请求应用头对象!");
        EsbReqServiceBean esbReqServiceBean = (EsbReqServiceBean) request.getAttribute("esbReqServiceBean");
        return esbReqServiceBean;
    }

    @ModelAttribute("nlsPsdPreCreditApprReqBean")
    public NlsPsdPreCreditApprReqBean getReqEsbBodyBean(HttpServletRequest request) {
        logger.info("获取ESB请求体！");
        String esbReqBody = (String) request.getAttribute("esbReqBody");
        return JSONObject.parseObject(esbReqBody, NlsPsdPreCreditApprReqBean.class);
    }

    /**
     *需求编号：【2019D1218】（普税贷需求）
     *问题编号：【2019D1218】（普税贷预授信申请失败返回信息）
     *开发人员：【ludayong】
     *创建日期：【2019/12/16 16:19】
     *功能描述：
     *修改日期：【2019/12/16 16:19】 
     *修改描述：
     */
    public EsbRespServiceBean failureHandler(EsbReqServiceBean esbReqServiceBean, NlsPsdPreCreditApprReqBean nlsPsdPreCreditApprReqBean, NlsPsdPreCreditApprRespBean nlsPsdPreCreditApprRespBean, Exception exception, EsbRetCodeStandard esbRetCodeStandard) {
        PreNlsCreditInfoVO inPreNlsCreditInfoVo = new PreNlsCreditInfoVO();
        // 渠道申请号
        String chanAppNo = nlsPsdPreCreditApprReqBean.getChanAppNo();
        // 预授信申请流水号
        inPreNlsCreditInfoVo.setApplySeq(chanAppNo);
        // 渠道申请号
        inPreNlsCreditInfoVo.setChannelApplyNo(chanAppNo);
        // 审批状态
        inPreNlsCreditInfoVo.setStatus(MsLoanConstant.NlsApplyStateEnum.REJECT.getVALUE());
        // 拒绝原因
        inPreNlsCreditInfoVo.setRefuseReason(exception.getLocalizedMessage());
        // 拒绝码
        inPreNlsCreditInfoVo.setRefuseCode(esbRetCodeStandard.getValue());
        // 审批时间
        inPreNlsCreditInfoVo.setApprovalTime(DateTool.getCurrentDateTime());
        // 最后更新人
        inPreNlsCreditInfoVo.setLastUpdateUser(BaseConstant.ADMIN);
        // 最后更新时间
        inPreNlsCreditInfoVo.setLastUpdateTime(DateTool.getCurrentDateTime());
        // 更预授信申请信息
        preNlsCreditInfoService.updateByPk(inPreNlsCreditInfoVo);

        logger.error("普税贷预授信申请接口出现异常，异常信息：" + exception.getMessage());
        nlsPsdPreCreditApprRespBean.setRetCd(esbRetCodeStandard.getValue());
        nlsPsdPreCreditApprRespBean.setRetMsg(exception.getLocalizedMessage());
        exception.printStackTrace();
        return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
                JSONObject.toJSONString(nlsPsdPreCreditApprRespBean, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteMapNullValue),
                EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
                esbRetCodeStandard.getValue(),
                exception.getMessage());
    }

    /**
     *需求编号：【2019D1218】（普税贷需求）
     *问题编号：【2019D1218】（普税贷预授信申请失败直接返回信息）
     *开发人员：【ludayong】
     *创建日期：【2019/12/16 16:19】
     *功能描述：
     *修改日期：【2019/12/16 16:19】
     *修改描述：
     */
    public EsbRespServiceBean failureNotHandle(EsbReqServiceBean esbReqServiceBean, NlsPsdPreCreditApprReqBean nlsPsdPreCreditApprReqBean, NlsPsdPreCreditApprRespBean nlsPsdPreCreditApprRespBean, Exception exception, EsbRetCodeStandard esbRetCodeStandard) {
        logger.error("普税贷预授信申请接口出现异常，异常信息：" + exception.getMessage());
        nlsPsdPreCreditApprRespBean.setRetCd(esbRetCodeStandard.getValue());
        nlsPsdPreCreditApprRespBean.setRetMsg(exception.getLocalizedMessage());
        exception.printStackTrace();
        return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
                JSONObject.toJSONString(nlsPsdPreCreditApprRespBean, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteMapNullValue),
                EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
                esbRetCodeStandard.getValue(),
                exception.getMessage());
    }

    // 预授信过程服务
    @Autowired
    @Qualifier("nlsPsdPreCreditProcessServcie")
    private NlsPsdPreCreditProcessServcie nlsPsdPreCreditProcessServcie;

    // 预授信申请信息表服务
    @Autowired
    @Qualifier("preNlsCreditInfoService")
    private PreNlsCreditInfoService preNlsCreditInfoService;

    @Autowired
    private NlsCreditInfoService nlsCreditInfoService;
}